package com.lz;

import org.apache.zookeeper.*;
import org.apache.zookeeper.data.ACL;
import org.apache.zookeeper.data.Id;
import org.apache.zookeeper.data.Stat;
import org.apache.zookeeper.server.auth.DigestAuthenticationProvider;

import java.io.IOException;
import java.security.NoSuchAlgorithmException;
import java.util.ArrayList;
import java.util.List;

public class ZookeeperDemo implements Watcher {
    private static Stat stat = new Stat();

    public static void main(String[] args) throws IOException, KeeperException, InterruptedException, NoSuchAlgorithmException {
        List<ACL> acls = addAuthority();
        ZooKeeper zooKeeper = new ZooKeeper("192.168.128.130", 5000, new ZookeeperDemo());
        // 获取连接状态
        ZooKeeper.States state = zooKeeper.getState();
        System.out.println(state);
        operation(zooKeeper, "/test03", acls, new Id("digest", "user1:123456a"));
    }

    private static void operation(ZooKeeper zooKeeper, final String path, List<ACL> list, Id... ids) throws InterruptedException, KeeperException {
        zooKeeper.create(path, "哈哈哈".getBytes(), list, CreateMode.PERSISTENT);
        zooKeeper.addAuthInfo("digest", "user1:123456a".getBytes());
        for (Id id : ids) {
            zooKeeper.addAuthInfo(id.getScheme(), id.getId().getBytes());
        }
        getACL(zooKeeper);
        // 修改前
        byte[] data = zooKeeper.getData(path, true, stat);
        System.out.println(new String(data));
        // 修改Data
        zooKeeper.setData(path, "我被修改了，加过权限".getBytes(), -1);
        data = zooKeeper.getData(path, true, stat);
        System.out.println(new String(data));
    }


    private static void getACL(ZooKeeper zooKeeper) throws KeeperException, InterruptedException {
        // 获取该节点的acl权限信息
        List<ACL> aclList = zooKeeper.getACL("/test01", stat);
        if (aclList != null && aclList.size() > 0) {
            for (ACL acl : aclList) {
                System.out.println("权限scheme id：" + acl.getId());
                // 获取的是十进制的int型数字
                System.out.println("权限位：" + acl.getPerms());
            }
        }
        // 避免与服务端的连接马上断开
        Thread.sleep(1000);

    }

    private static List<ACL> addAuthority() throws NoSuchAlgorithmException {
        // 自定义用户认证访问
        List<ACL> acls = new ArrayList<ACL>();  // 权限列表
        // 第一个参数是权限scheme，第二个参数是加密后的用户名和密码
        Id user1 = new Id("digest", DigestAuthenticationProvider.generateDigest("user1:123456a"));
        Id user2 = new Id("digest", DigestAuthenticationProvider.generateDigest("user2:123456a"));
        acls.add(new ACL(ZooDefs.Perms.ALL, user1));  // 给予所有权限
        acls.add(new ACL(ZooDefs.Perms.READ, user2));  // 只给予读权限
        acls.add(new ACL(ZooDefs.Perms.DELETE | ZooDefs.Perms.CREATE, user2));  // 多个权限的给予方式，使用 | 位运算符
        return acls;

    }

    // 回调方法
    @Override
    public void process(WatchedEvent watchedEvent) {

        Event.KeeperState state = watchedEvent.getState();
        if (state.equals(Event.KeeperState.SyncConnected)) {
            Event.EventType type = watchedEvent.getType();
            if (Event.EventType.NodeCreated.equals(type)) {
                System.out.println("正在创建。。。");
            } else if (Event.EventType.NodeDataChanged.equals(type)) {
                System.out.println("正在修改。。。");
            }

        }
    }
}
